package com.atguigu.lease.web.admin.service.impl;


import com.atguigu.lease.common.config.MinioConfig;
import com.atguigu.lease.common.exception.StgyException;
import com.atguigu.lease.common.result.ResultCodeEnum;
import com.atguigu.lease.web.admin.service.FileService;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.RemoveObjectArgs;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.util.List;
import java.util.UUID;

//@EnableConfigurationProperties(value = MinioConfig.class)
@Service
@Slf4j
public class FileServiceImpl implements FileService {
    @Resource
    MinioClient minioClient;

    //硬编码
    @Override
    public String upload(MultipartFile file) {
        try {
            //1、获取文件信息： 文件校验 ， 文件名称
            InputStream is = file.getInputStream();
            if(is.available()==0){
                throw new RuntimeException("上传文件错误");
            }
            String contentType = file.getContentType().toLowerCase();
            //获取文件名称
            String filename = file.getOriginalFilename();
            //截取文件的扩展名
            String suffix = filename.substring(filename.lastIndexOf(".")).toLowerCase();
            if(!MinioConfig.MEDIA_TYPES
                    .contains(suffix) //如果集合中包含文件的扩展名放行继续执行
            ){
                throw new RuntimeException("上传文件类型错误");
            }
            //2、拼接保存到桶内的文件路径和文件名称
            String objectName = MinioConfig.MODULE + //本次上传的文件要保存到桶内的哪个子目录下
                    new DateTime().toString("/yyyy/MM/dd/") + //时间日期路径
                    System.currentTimeMillis()+"_"+ UUID.randomUUID().toString().substring(0,6)+ //唯一文件名称
                    suffix;
            minioClient.putObject(PutObjectArgs.builder()
                    .bucket(MinioConfig.BUCKET)
                    .stream(is , is.available(),-1)
                    //要写入到桶内的文件路径&文件名称
                    .object(objectName)
                    //设置文件的contenttype：可以通过spring-web包提供的MediaType来获取文件类型
                    .contentType(contentType) //给上传的文件设置mediaType
                    .build());
            //3、拼接上传成功的文件路径：
            //http://192.168.123.111:9000/demo02/test/2024/08/27/1724722442151_4e8e17.png
            String imgUrl = MinioConfig.ENDPOINT+"/"+MinioConfig.BUCKET+"/" +objectName;
            return imgUrl;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }

    @Override
    public String delete(String path) {
        //http://192.168.123.111:9000/stgy/image/2024/08/27/1724726524070_d50925.jpg
        try {
            int beginIndex = (MinioConfig.ENDPOINT+"/"+MinioConfig.BUCKET+"/").length();
            String objectName = path.substring(beginIndex);
            minioClient.removeObject(RemoveObjectArgs.builder()
                    .bucket(MinioConfig.BUCKET)
                    .object(objectName).build());
            return "success";
        } catch (Exception e) {
            throw new StgyException( ResultCodeEnum.FILE_DELETE_ERROR, e);
        }
    }
    @Async //异步执行: spring通过aop开子线程执行
    // 线程资源需要我们人为控制： 线程数量
    @Override
    public void batchDelete(List<String> graphUrls,Long id) {
        //整个业务执行结束：删除房间的图片  避免业务失败回滚时图片被删除了
        //graphUrls : 图片删除失败一般不能影响主业务
        try {
//            Thread.sleep(10000);
            for (String url : graphUrls) {
                this.delete(url);
            }
        } catch (Exception e) {
//            throw new RuntimeException(e);
            log.error("stgy-roominfo-图片删除失败: url= {},roomId = {}" ,
                    StringUtils.join(graphUrls,",") , id);
        }
    }
}
